﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Media.Animation;
using System.Windows.Markup;
using System.Windows.Controls.Primitives;


namespace UmlControlLibrary
{
    public class UmlArrow : SelectableItemControl
    {
        public string Label
        {
            get;
            set;
        }
        public PathFigure Figure
        {
            get;
            set;
        }

        public Point P1
        {
            get;
            set;
        }

        public Point P2
        {
            get;
            set;
        }

        public virtual PathFigure CalculateArrow(out Point correctedPoint)
        {
            PathFigure pathfig = this.Figure;
            correctedPoint = P2;
            return pathfig;
        }

        public virtual void UpdateArrow(Point p1, Point p2)
        {
            P1 = p1;
            P2 = p2;
            if ((p1.X != p2.X) || (p1.Y != p2.Y))
                CalculateArrow(out p2);
            else
                Figure.Segments.Clear();
            P2 = p2;
        }

        public UmlArrow(string label, Point p1, Point p2)
            : base()
        {
            Figure = new PathFigure();
            this.P1 = p1;
            this.P2 = p2;
            CalculateArrow(out p2);
            this.P2 = p2;
        }
    }

    public class UmlArrowInheritance : UmlArrow
    {
        public UmlArrowInheritance(string label, Point p1, Point p2)
            : base(label, p1, p2)
        {

        }

        public override PathFigure CalculateArrow(out Point correctedPoint)
        {
            PathFigure pathfig = this.Figure;

            double ArrowLength = 15;
            double ArrowAngle = 45;
            bool IsArrowClosed = true;

            Matrix matx = new Matrix();
            Vector vect = P1 - P2;
            vect.Normalize();
            vect *= ArrowLength;

            PolyLineSegment polyseg;
            if (pathfig.Segments.Count == 0)
            {
                polyseg = new PolyLineSegment();
                pathfig.Segments.Add(polyseg);
            }
            else
                polyseg = (PolyLineSegment)pathfig.Segments[0];
            polyseg.Points.Clear();
            matx.Rotate(ArrowAngle / 2);
            //            pathfig.StartPoint = (pt2 - vect) + vect * matx;
            //            polyseg.Points.Add((pt2 - vect));
            pathfig.StartPoint = P2 + vect * matx;
            polyseg.Points.Add(P2);

            matx.Rotate(-ArrowAngle);
            //            polyseg.Points.Add((pt2 - vect) + vect * matx);
            polyseg.Points.Add(P2 + vect * matx);
            pathfig.IsClosed = IsArrowClosed;
            pathfig.IsFilled = true;

            correctedPoint = P2 + vect;

            return pathfig;
        }
    }

    public class UmlArrowDiamond : UmlArrow
    {
        public UmlArrowDiamond(string label, Point p1, Point p2)
            : base(label, p1, p2)
        {

        }
        public override PathFigure CalculateArrow(out Point correctedPoint)
        {
            PathFigure pathfig = this.Figure;

            double ArrowLength = 10;
            double ArrowAngle = 45;
            bool IsArrowClosed = true;

            Matrix matx = new Matrix();
            Vector vect = P1 - P2;
            vect.Normalize();
            vect *= ArrowLength;

            PolyLineSegment polyseg;
            if (pathfig.Segments.Count == 0)
            {
                polyseg = new PolyLineSegment();
                pathfig.Segments.Add(polyseg);
            }
            else
                polyseg = (PolyLineSegment)pathfig.Segments[0];
            polyseg.Points.Clear();
            matx.Rotate(ArrowAngle / 2);
            //            pathfig.StartPoint = (pt2 - vect) + vect * matx;
            //            polyseg.Points.Add((pt2 - vect));
            pathfig.StartPoint = P2 + vect * matx;
            polyseg.Points.Add(P2);

            matx.Rotate(-ArrowAngle);
            //            polyseg.Points.Add((pt2 - vect) + vect * matx);

            polyseg.Points.Add(P2 + vect * matx);

            correctedPoint = pathfig.StartPoint + vect * matx;
            polyseg.Points.Add(correctedPoint);

            pathfig.IsClosed = IsArrowClosed;
            pathfig.IsFilled = true;

            return pathfig;
        }
    }

}
